<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <link href="/layui/lib/css/layui.css" rel="stylesheet" type="text/css" />
    <script src="/layui/lib/layui.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/Sortable/1.15.2/Sortable.min.js"></script>
    <style class="text/css">
        #leftNav{
            border: 1px solid #ccc;
            min-height: 600px;
        }

        #designArea{
            border: 1px solid #ccc;
            margin-left: 8px;
            min-height: 600px;
        }

        .ctrlItem{
            min-width: 60px;
            min-height: 20px;
        }

        .ctrlItemInfo{
            border: 1px solid #000;
        }

        .canPut{

        }

        .canPull{

        }

        .minHeight{

        }

        .ctrlItemOver{
            border: 1px solid #000;
        }

    </style>
</head>
<body>


    <blockquote class="layui-elem-quote">sortable.js调试</blockquote>
    

<div class="layui-row">
    <div class="layui-col-md1 " id="leftNav">
        <button class="ctrl ctrlButton">按钮</button>
        <button class="ctrl ctrlDiv">容器</button>
        <button class="ctrl ctrlLayuiRow">Layui行</button>
    </div>
    <div class="layui-col-md11">
        
        <div class="layui-row">设计区</div>
        <div id="designArea" class="ctrlItem">

            <div class="layui-row ctrlItem ctrlItemInfo">abc</div>

            <div class="ctrlItem">
                <button>add</button>
                <button>modify</button>
            </div>
           
        </div>
        <div>
            <div class="layui-row">
                <textarea class="layui-textarea" id="ctrlDefine">

                </textarea>
            </div>
            <div class="layui-row"><button class="layui-btn" id="btnSaveCtrlDefine">保存定义</button></div>
        </div>


    </div>
</div>


    <script>
        var util = {
            getHtmlAttr : function(attrMap){
                var strInfo = "";
                $.each(attrMap,function(i,item){
                    strInfo += item.key +"=\"" + item.value + "\" ";
                });

                if(strInfo !== ""){
                    strInfo = strInfo.substr(0, strInfo.length - 1);
                }

                return strInfo;
            },
            getAttr : function(){
                
            }
        }


        var ctrlMaxId = 0;
        var ayCtrl = {

            ctrlDefine:[
                {
                    ctrlType:"ctrlButton",
                    ctrlCaption:"按钮",
                    classList:"",
                    caption:"按钮"
                },
                {
                    ctrlType:"ctrlDiv",
                    ctrlCaption:"普通容器",
                },
                {
                    ctrlType:"ctrlLayuiRow",
                    ctrlCaption:"Layui行"
                },
                {
                    ctrlType:"ctrlLayuiInput",
                    ctrlCaption:"Layui输入框"
                },
                {
                    ctrlType:"ctrlLayuiRowCol",
                    ctrlCaption:"Layui行列"
                },
                {
                    ctrlType:"ctrlLayuiTab",
                    ctrlCaption:"LayuiTab"
                },
                {
                    ctrlType:"ctrlLayuiTabItem",
                    ctrlCaption:"LayuiTabItem"
                },
            ],
            getNewCtrlId : function(){
                ctrlMaxId++;
                return "el" + ctrlMaxId;
            },
            //根据类型得到通用的属性
            getCommonHtmlAttr: function(define){
                if(typeof(define) === "undefined"){
                    return "";
                }

                var attrInfo = "";
                var id = define.id;
                if(typeof(id) === "undefined" || id === ""){
                    id = ayCtrl.getNewCtrlId();
                }

                attrInfo += "id=\"" + id + "\" ";

                // classList
                var classInfo = define.classList;
                if(typeof(classInfo) === "undefined" || define.classList === ""){
                    classInfo = "";
                }

                if(classInfo !== ""){
                    classInfo +=" " + "ctrlItem";
                }
                else{
                    classInfo ="ctrlItem";
                }

                var canPutList = "ctrlDiv, ctrlLayuiRow, ctrlLayuiRowCol, ctrlLayuiTabItem,";
                if(canPutList.indexOf(define.ctrlType+",") > -1){
                    classInfo +=" canPut"
                }
                
                if(attrInfo !== ""){
                    attrInfo +=" " + "class=\"" + classInfo + "\"";
                }
                else{
                    attrInfo +="class=\"" + classInfo + "\"";
                }

                //name
                var nameInfo = define.name;
                if(typeof(nameInfo) === "undefined"){
                    nameInfo ="";
                }

                if(attrInfo != ""){
                    attrInfo += " " + nameInfo;
                }

                return attrInfo;

            },
            renderCtrl:function(define){
                console.log("define",define);

                var html = "";

                console.log("define",define);

                if(typeof(define) == "undefined"){
                    console.log("不存在当前的控件类型");
                    return "";
                }

                var ctrlType = define.ctrlType;
                console.log("ctrlType",ctrlType);

                if(ctrlType === "ctrlButton"){
                    html = ayCtrl.getButton(define);
                    return html;
                }

                if(ctrlType === "ctrlDiv"){
                    html = ayCtrl.getDiv(define);
                    return html;
                }
                
                if(ctrlType === "ctrlLayuiRow"){
                    html = ayCtrl.getLayuiRow(define);
                    return html;
                }

                if(ctrlType === "ctrlLayuiRowCol"){
                    html = ayCtrl.getLayuiRowCol(define);
                    return html;
                }

                if(ctrlType === "ctrlLayuiTab"){
                    html = ayCtrl.getLayuiTab(define);
                    return html;
                }

                if(ctrlType === "ctrlLayuiInput"){
                    html = ayCtrl.getLayuiInput(define);
                    return html;
                }

            },
            getButton:function(config){
                

                var attrInfo = ayCtrl.getCommonHtmlAttr(config);
                console.log("getButton attrInfo",attrInfo)

                var caption = config.caption;
                if(typeof(caption) === "undefined"){
                    caption = "按钮";
                }

                var html = "<button "+attrInfo+">"+caption+"</button>";
                return html;
            },
            getDiv:function(config){
                var ctrlId = ayCtrl.getNewCtrlId();
                var html = "<div id=\""+ctrlId+"\" class='ctrlItem canPut'></div>";
                return html;
            },
            getLayuiRow:function(config){
                var ctrlId = ayCtrl.getNewCtrlId();
                var html = "<div id=\""+ctrlId+"\" class='layui-row canPut ctrlItem'></div>";
                return html;
            },
            getLayuiRowCol:function(config){
                var ctrlId = ayCtrl.getNewCtrlId();
                var html = "<div id=\""+ctrlId+"\" class='layui-col-md6 canPut ctrlItem'></div>";
                return html;
            },
            getLayuiInput:function(config){
                var ctrlId = ayCtrl.getNewCtrlId();
                var html = "<input id=\""+ctrlId+"\" class='layui-input ctrlItem' />";
                return html;
            },
            getLayuiTab:function(config){
                var ctrlId = ayCtrl.getNewCtrlId();
                var pre = "<div class=\"layui-tab ctrlItem\" id=\""+ctrlId+"\">";
                var tabtitle = "<ul class=\"layui-tab-title\"><li class=\"layui-this\">选项1</li></ul>";
                var tabContent = "<div class=\"layui-tab-content\"><div class=\"layui-tab-item layui-show ctrlItem canPut\"></div></div>"
                var suffix = "</div>"
                var html = pre + tabtitle + tabContent + suffix;
                return html;
            }
            

        };
    
    var ayForm = {

        CtrlList:[],
        //开始初始化
        init:function(){
            // 初始化左侧
            new Sortable(document.getElementById('leftNav'), {
                group: {
                    name: 'shared', // 组名
                    pull: "clone",     // 允许拖出元素
                    put: false       // 允许放入元素
                },
                animation: 150,

            }); 

            this.initLefNavCtrl();
            this.initDesignSortable();
            this.initCtrlSort();
            this.initEvent();

        },

        initLefNavCtrl:function(){
            $("#leftNav").html("");
            $(ayCtrl.ctrlDefine).each(function(i,define){
                var cloneDefine = $.extend({},define);
                var ctrlType = cloneDefine.ctrlType;
                var button = "<button class=\"ctrl "+cloneDefine.ctrlType+"\">"+cloneDefine.ctrlCaption+"</button>";

                $("#leftNav").append(button);
            });
        },

        initEvent:function(){

            //
            $("body").on("mouseover",".ctrlItem",function(){
                $(this).addClass("ctrlItemOver")
            })

            $("body").on("mouseout",".ctrlItem",function(){
                $(this).removeClass("ctrlItemOver")
            })

            //保存控件定义

            $("body").on("click","#btnSaveCtrlDefine",function(){
                var config = JSON.parse($("#ctrlDefine").val());
                var html = ayCtrl.renderCtrl(config);
                console.log("html",html);
                var ctrlId = config.id;
                //插入新的html 同时将自身给移除掉
                $("#"+ctrlId).after(html).remove();
            })
        },
        putEl:function(to,from,dragEl,event){
            console.log("to",to);
            console.log("from",from);
            console.log("dragEl",dragEl);

            //判断是否可以放入什么样的新元素
            if($(from.el).attr("id") === "leftNav"){
                //表示来源于左侧
                //var curCtrl = $(dragEl).hasClass("ctrlButton")

                if(!($(to.el).hasClass("canPut"))){
                    console.log("无移入类，则不能移入");
                    return false;
                }
            } 

            if($(from.el).hasClass("ctrlItem")){
                //
                if(!($(to.el).hasClass("canPut"))){
                    console.log("无移入类，则不能移入");
                    return false;
                }
            }


            console.log("看有没有执行...");
            return true;
        },
        pullEl:function(to,from,dragEl,event){
            console.log("to",to);
            console.log("from",from);
            console.log("dragEl",dragEl);

            var classInfo = $(dragEl).attr("class");
            if(classInfo.indexOf("layui-col-md")){
                return false;
            }


            return true;
        },
        addEl:function(evt){

            //在设计的元素在各个容器中互相拖动的
            if($(evt.from).attr("id") === "leftNav"){
                console.log("从左侧菜单中入设计区");
                ayForm.addElFromLeftNav(evt);
            } 
            else{
                if($(evt.from).hasClass("ctrlItem")){
                    console.log("设计区控件之间互相移入");
                    ayForm.addElFromDesign(evt);
                }
            }

            //对新增加的元素赋值新的移动属性
            ayForm.initCtrlSort();
            return false;

        },
        addElFromDesign(evt){
           console.log("addElFromDesign",evt);
        },
        addElFromLeftNav:function(evt){
            console.log("addElFromLeftNav",evt);
            var dragItem = evt.item;
            
            var targetContainer = evt.to;

            //原始先移除掉
            $(dragItem).remove();

            //将新的html进行解析
            var newHtml = "";

            $(ayCtrl.ctrlDefine).each(function(i,define){
               
                var config = $.extend({},define);
                var ctrlType = config.ctrlType;
                if($(dragItem).hasClass(ctrlType)){
                    newHtml = ayCtrl.renderCtrl(config);
                    console.log("newHtml",newHtml);
                    return false;
                }
            });
            
            

            if(newHtml !== ""){
                $(targetContainer).append(newHtml);
            }
            
            return "";

        },
        initCtrlSort:function(){
            var ctrlList = document.getElementsByClassName('ctrlItem');
            console.log("ctrlList",ctrlList);

             // 遍历每个容器并初始化 Sortable
             Array.from(ctrlList).forEach(container => {
                new Sortable(container, {
                    group: {
                            name: 'shared', // 组名
                            pull: function(to,from,dragEl,event){
                                return ayForm.pullEl(to,from,dragEl,event);
                            },     
                            // 允许拖出元素
                            put: function(to,from,dragEl){
                                return ayForm.putEl(to,from,dragEl);
                            }
                        },
                        draggable:".ctrlItem",
                        animation: 150,
                        sort:true,
                        forcePlaceholderSize: true,
                        onAdd:function(evt){
                            ayForm.addEl(evt);
                        }
                });
            });

        },
        //初始化设计区排序值
        initDesignSortable:function(){
            //初始化排序
            // 初始化右侧
            new Sortable(document.getElementById('designArea'), {
                        group: {
                            name: 'shared', // 组名
                            pull: true,     // 允许拖出元素
                            put: true       // 允许放入元素
                        },
                        animation: 150,
                        draggable:".ctrlItem",
                        sort:true,
                        forcePlaceholderSize: true,
                        onAdd:function(evt){
                            ayForm.addEl(evt);
                        }
                    }); 


        }

    }

    ayForm.init();

    </script>
</body>
</html>